// development ssr
const Router = require('koa-router')
const axios = require('axios')
const path = require('path')
const fs = require('fs')
const MemoryFs = require('memory-fs') // 与fs区别是不把文件写入磁盘而是写入内存，提高读取、输出文件的效率
const webpack = require('webpack')
const VueServerRenderer = require('vue-server-renderer') // 渲染的文件必须是json

const serverRender = require('./server-render')
const serverConfig = require('../../build/webpack.config.server')

const serverCompiler = webpack(serverConfig)
const mfs = new MemoryFs()
serverCompiler.outputFileSystem = mfs // 指定输出目录

let bundle // 记录webpack每次打包生成的文件
serverCompiler.watch({}, (err, stats) => { // watch每次改了文件都会重新自动打包，类似dev-server
  if (err) throw err
  stats = stats.toJson()
  stats.errors.forEach(err => console.log(err)) // eslint的错误
  stats.warnings.forEach(warn => console.warn(err)) // eslint的错误

  // 读取bundle文件
  const bundlePath = path.join(
    serverConfig.output.path,
    'vue-ssr-server-bundle.json' // 默认文件名
  )
  bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')) // 不指定utf-8会返回二进制数据,由于VueServerRenderer只能读取json,所以这里要把字符串转换为json
  console.log('new bundle generated by WQ')
})

const handleSSR = async (ctx) => {
  if (!bundle) { // 当第一次进入该应用，当前的bundle还没打包完成显示提醒
    ctx.body = '稍等一会儿'
    return
  }

  const clientManifestResp = await axios.get(
    'http://127.0.0.1:4000/public/vue-ssr-client-manifest.json'
  )

  const clientManifest = clientManifestResp.data

  const template = fs.readFileSync(
    path.join(__dirname, '../server.template.ejs'), 'utf-8'
  ) // 也要转换为utf-8，不然无法解析模板

  const renderer = VueServerRenderer.createBundleRenderer(bundle, {
    inject: false,
    clientManifest
  })
  console.log(renderer)
  await serverRender(ctx, renderer, template)
}
const router = new Router()
router.get('*', handleSSR) // 所有的请求都用handleSSRl来处理

module.exports = router
